// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#include <nebula/bits/bit_run_reader.h>
#include <nebula/bits/bit_util.h>
#include <cstdint>


namespace nebula {
namespace internal {

#if NEBULA_LITTLE_ENDIAN

BitRunReader::BitRunReader(const uint8_t* bitmap, int64_t start_offset, int64_t length)
    : bitmap_(bitmap + (start_offset / 8)),
      position_(start_offset % 8),
      length_(position_ + length) {
  if (TURBO_UNLIKELY(length == 0)) {
    word_ = 0;
    return;
  }

  // On the initial load if there is an offset we need to account for this when
  // loading bytes.  Every other call to LoadWord() should only occur when
  // position_ is a multiple of 64.
  current_run_bit_set_ = !bit_util::get_bit(bitmap, start_offset);
  int64_t bits_remaining = length + position_;

  LoadWord(bits_remaining);

  // Prepare for inversion in NextRun.
  // Clear out any preceding bits.
  word_ = word_ & ~bit_util::LeastSignificantBitMask(position_);
}

#endif

}  // namespace internal
}  // namespace nebula
